package handler

import (
	"context"
	"github.com/golang/protobuf/ptypes/empty"
	"github.com/golang/protobuf/ptypes/wrappers"

	"kop/framework/broker"
	context2 "kop/framework/context"
	"kop/libs/database"
	"kop/modules/chat/entity"
	"kop/modules/chat/models"
	"kop/modules/configuration/configuration/keyword"
	"kop/pb"
	"math"

	roleC "kop/modules/role/client"
)

type ChatServiceHandler struct {
	context2.Context
}

func (h *ChatServiceHandler) ServerChats(ctx context.Context, req *wrappers.Int32Value, resp *pb.Chats) error {

	var chats, err = models.GetServerChats(database.DB, h.GetServerID(ctx), req.Value, 10)
	if err != nil {
		return err
	}

	resp.Chats = make([]*pb.Chat, 0, len(chats))
	for _, chat := range chats {
		resp.Chats = append(resp.Chats, buildPbServerChat(chat))
	}

	return nil
}

func (h *ChatServiceHandler) SendServerChat(ctx context.Context, req *wrappers.StringValue, _ *empty.Empty) error {

	var msg = []rune(keyword.KeyWords.Replace(req.Value))

	var role = roleC.GetRole(h.GetRoleID(ctx))

	var chat = entity.ServerChat{
		ServerID: h.GetServerID(ctx),
		RoleID:   h.GetRoleID(ctx),
		Name:     role.Name,
		Photo:    role.Photo,
		VIP:      role.VIP,
		Level:    role.Level,
		Content:  string(msg[:int(math.Min(float64(len(msg)), 50))]),
	}

	database.DB.Create(&chat)
	_ = broker.ServerPublish(h.GetServerID(ctx), pb.WsCode_CodeServerChat, buildPbServerChat(chat))

	return nil
}

func (h *ChatServiceHandler) GuildChats(ctx context.Context, req *wrappers.Int32Value, resp *pb.Chats) error {

	var guildID = h.GetGuildID(ctx)
	if guildID == 0 {
		return nil
	}

	var chats []entity.GuildChat
	if err := database.DB.Where(entity.GuildChat{GuildID: guildID}).Order("id DESC").Limit(10).Offset((req.Value - 1) * 10).Find(&chats).Error; err != nil {
		return err
	}

	resp.Chats = make([]*pb.Chat, 0, len(chats))
	for _, chat := range chats {
		resp.Chats = append(resp.Chats, buildPbGuildChat(chat))
	}

	return nil
}

func (h *ChatServiceHandler) SendGuildChat(ctx context.Context, req *wrappers.StringValue, _ *empty.Empty) error {

	var msg = []rune(keyword.KeyWords.Replace(req.Value))

	var guildID = h.GetGuildID(ctx)
	if guildID == 0 {
		return nil
	}

	var role = roleC.GetRole(h.GetRoleID(ctx))

	var chat = entity.GuildChat{
		GuildID: guildID,
		RoleID:  role.RoleID,
		Name:    role.Name,
		Photo:   role.Photo,
		VIP:     role.VIP,
		Level:   role.Level,
		Content: string(msg[:int(math.Min(float64(len(msg)), 50))]),
	}

	database.DB.Create(&chat)
	_ = broker.GuildPublish(guildID, pb.WsCode_CodeGuildChat, buildPbGuildChat(chat))

	return nil
}

func buildPbServerChat(chat entity.ServerChat) *pb.Chat {

	var message = &pb.Chat{
		ID:        chat.ID,
		RoleID:    chat.RoleID,
		Name:      chat.Name,
		Photo:     chat.Photo,
		VIP:       chat.VIP,
		Level:     chat.Level,
		Content:   chat.Content,
		Timestamp: chat.CreatedAt.Unix(),
	}

	return message
}

func buildPbGuildChat(chat entity.GuildChat) *pb.Chat {

	return &pb.Chat{
		ID:        chat.ID,
		RoleID:    chat.RoleID,
		Name:      chat.Name,
		Photo:     chat.Photo,
		VIP:       chat.VIP,
		Level:     chat.Level,
		Content:   chat.Content,
		Timestamp: chat.CreatedAt.Unix(),
	}
}
